#include <QLoggingCategory>

#include "qcamera.h"
#include "qmediaserviceproviderplugin.h"
#include "qopenharmonymediaserviceplugin.h"
#include "mediacapture/qopenharmonycamerasession.h"
#include "mediacapture/qopenharmonycaptureservice.h"
#include "mediacapture/qopenharmonycamerainfocontrol.h"
#include "qopenharmonyplayerservice.h"
#include "player/qopenharmonyplayer.h"
#include "player/qopenharmonywindowcontrol.h"

QT_BEGIN_NAMESPACE

Q_LOGGING_CATEGORY(qtOPenHaronyMediaPlugin, "qt.multimedia.plugins.openharmony")

QOPenHarmonyMediaServicePlugin::QOPenHarmonyMediaServicePlugin()
{
}

QOPenHarmonyMediaServicePlugin::~QOPenHarmonyMediaServicePlugin()
{
}

QMediaService *QOPenHarmonyMediaServicePlugin::create(const QString &key)
{
    if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER))
        return new QOpenHarmonyPlayerService;

    if (key == QLatin1String(Q_MEDIASERVICE_CAMERA)
            || key == QLatin1String(Q_MEDIASERVICE_AUDIOSOURCE)) {
        return new QOPenHarmonyCaptureService(key);
    }

    qCWarning(qtOPenHaronyMediaPlugin) << "OPenHarony service plugin: unsupported key:" << key;
    return 0;
}

void QOPenHarmonyMediaServicePlugin::release(QMediaService *service)
{
    delete service;
}

QMediaServiceProviderHint::Features QOPenHarmonyMediaServicePlugin::supportedFeatures(const QByteArray &service) const
{
    if (service == Q_MEDIASERVICE_MEDIAPLAYER)
        return QMediaServiceProviderHint::VideoSurface;

    if (service == Q_MEDIASERVICE_CAMERA)
        return QMediaServiceProviderHint::VideoSurface | QMediaServiceProviderHint::RecordingSupport;

    if (service == Q_MEDIASERVICE_AUDIOSOURCE)
        return QMediaServiceProviderHint::RecordingSupport;

    return QMediaServiceProviderHint::Features();
}

QByteArray QOPenHarmonyMediaServicePlugin::defaultDevice(const QByteArray &service) const
{
    if (service == Q_MEDIASERVICE_CAMERA && !QOPenHarmonyCameraSession::availableCameras().isEmpty())
        return QOPenHarmonyCameraSession::availableCameras().first().name;

    return QByteArray();
}

QList<QByteArray> QOPenHarmonyMediaServicePlugin::devices(const QByteArray &service) const
{
    Q_UNUSED(service);
    if (service == Q_MEDIASERVICE_CAMERA) {
        QList<QByteArray> devices;
        const QList<OPenHarmonyCameraInfo> &cameras = QOPenHarmonyCameraSession::availableCameras();
        for (int i = 0; i < cameras.count(); ++i)
            devices.append(cameras.at(i).name);
        return devices;
    }

    return QList<QByteArray>();
}

QString QOPenHarmonyMediaServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device)
{
    if (service == Q_MEDIASERVICE_CAMERA) {
        const QList<OPenHarmonyCameraInfo> &cameras = QOPenHarmonyCameraSession::availableCameras();
        for (int i = 0; i < cameras.count(); ++i) {
            const OPenHarmonyCameraInfo &info = cameras.at(i);
            if (info.name == device)
                return info.description;
        }
    }

    return QString();
}

QCamera::Position QOPenHarmonyMediaServicePlugin::cameraPosition(const QByteArray &device) const
{
    return QOPenHarmonyCameraInfoControl::position(device);
}

int QOPenHarmonyMediaServicePlugin::cameraOrientation(const QByteArray &device) const
{
    return QOPenHarmonyCameraInfoControl::orientation(device);
}

QT_END_NAMESPACE


EXTERN_C_START static napi_value Init(napi_env env, napi_value exports) {
    static bool inited = false;
    if (!inited) {
        inited = true;
        QOpenHarmonyPlayer::init(env, exports);
    }
    QOpenHarmonyWindowControl::init(env, exports);
    return exports;
}
EXTERN_C_END

static napi_module multiMediaModule = {
    .nm_version = 1,
    .nm_flags = 0,
    .nm_filename = nullptr,
    .nm_register_func = Init,
    .nm_modname = "plugins_mediaservice_qtmedia_openharmony",
    .nm_priv = ((void *)0),
    .reserved = {0},
};

extern "C" __attribute__((constructor)) void RegisterModule(void) { napi_module_register(&multiMediaModule); }
